package com.william.jdbcplus.core.toolkit.json;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.parser.Feature;
import com.alibaba.fastjson.parser.ParserConfig;
import com.alibaba.fastjson.serializer.SerializeConfig;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.alibaba.fastjson.serializer.SimpleDateFormatSerializer;
import com.alibaba.fastjson.serializer.ToStringSerializer;
import com.alibaba.fastjson.support.config.FastJsonConfig;

import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * JSON工具类
 *
 * @author Fanjc
 */
public class JsonUtil {

    private static FastJsonConfig fastJsonConfig = getFastJsonConfig();

    private static ParserConfig parserConfig = getParserConfig();

    /**
     * 对象转美化JSON
     *
     * @param obj
     * @return
     */
    public static String toPrettyJson(Object obj) {
        return JSON.toJSONString(obj, fastJsonConfig.getSerializeConfig(), fastJsonConfig.getSerializerFeatures());
    }

    /**
     * 对象转JSON
     *
     * @param obj
     * @return
     */
    public static String obj2json(Object obj) {
        return JSON.toJSONString(obj, fastJsonConfig.getSerializeConfig(), fastJsonConfig.getSerializerFeatures());
    }

    /**
     * JSON转对象
     */
    public static <T> T json2obj(String jsonStr, Class<T> clazz) {
        return JSON.parseObject(jsonStr, clazz, parserConfig);
    }

    /**
     * 对象转对象
     */
    public static <T> T map(Object obj, Class<T> clazz) {
        String json = obj2json(obj);
        return JSON.parseObject(json, clazz, parserConfig);
    }

    /**
     * 对象LIST转对象LIST
     */
    public static <T> List<T> mapList(List<?> listObj, Class<T> clazz) {
        String json = obj2json(listObj);
        return json2list(json, clazz);
    }

    /**
     * JSON转对象列表
     */
    public static <T> List<T> json2list(String jsonArrayStr, Class<T> clazz) {
        return JSON.parseArray(jsonArrayStr, clazz, parserConfig);
    }

    /**
     * @return
     */
    private static FastJsonConfig getFastJsonConfig() {
        FastJsonConfig config = new FastJsonConfig();

        SerializeConfig mapping = new SerializeConfig();
        mapping.put(Date.class, new SimpleDateFormatSerializer("yyyy-MM-dd HH:mm:ss"));
        mapping.put(BigInteger.class, ToStringSerializer.instance);
        mapping.put(Long.class, ToStringSerializer.instance);
        mapping.put(Long.TYPE, ToStringSerializer.instance);
        config.setSerializeConfig(mapping);

        List<Feature> features = new ArrayList<>();
        features.add(Feature.AllowArbitraryCommas);
        features.add(Feature.AllowUnQuotedFieldNames);
        features.add(Feature.DisableCircularReferenceDetect);
        config.setFeatures(features.toArray(new Feature[features.size()]));

        List<SerializerFeature> serializerFeatures = new ArrayList<>();
        serializerFeatures.add(SerializerFeature.PrettyFormat);
        serializerFeatures.add(SerializerFeature.WriteDateUseDateFormat);
        serializerFeatures.add(SerializerFeature.WriteMapNullValue);
        //serializerFeatures.add(SerializerFeature.WriteNullStringAsEmpty);
        serializerFeatures.add(SerializerFeature.WriteNullListAsEmpty);
        serializerFeatures.add(SerializerFeature.IgnoreNonFieldGetter);
        serializerFeatures.add(SerializerFeature.DisableCircularReferenceDetect);
        config.setSerializerFeatures(serializerFeatures.toArray(new SerializerFeature[serializerFeatures.size()]));

        return config;
    }

    private static ParserConfig getParserConfig() {
        JsonParserConfig config = new JsonParserConfig();
        return config;
    }
}